/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is Forte for Java, Community Edition. The Initial
* Developer of the Original Code is Sun Microsystems, Inc. Portions
* Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
*/
package org.openide.loaders;
import java.beans.*;
import java.io.*;
import java.util.Enumeration;
import java.util.Vector;
import org.openide.TopManager;
import org.openide.filesystems.*;
import org.openide.util.SharedClassObject;
import org.openide.util.actions.SystemAction;
/** A data loader recognizes {@link FileObject}s and creates appropriate
* {@link DataObject}s to represent them.
* The created data object must be a subclass
* of the <EM>representation class</EM> provided in the constructor.
* <P>
* Subclasses of <code>DataLoader</code> should be made <EM>JavaBeans</EM> with
* additional parameters, so a user may configure the loaders in the loader pool.
*
* @author Jaroslav Tulach
*/
public abstract class DataLoader extends SharedClassObject {
/** property name of display name */
public static final String PROP_DISPLAY_NAME = "displayName"; // NOI18N
/** property name of list of actions */
public static final String PROP_ACTIONS = "actions"; // NOI18N
/** representation class, not public property */
private static final Object PROP_REPRESENTATION_CLASS = new Object ();
/** Create a new data loader.
* Pass its representation class
* as a parameter to the constructor. The constructor is then allowed
* to return only subclasses of the representation class as the result of
* {@link #findDataObject}.
*
* @param representationClass the superclass for all objects returned from
* {@link #findDataObject}. The class may be anything but
* should be chosen to be as close as possible to the actual class of objects returned from the loader,
* to best identify the loader's data objects to listeners.
*/
protected DataLoader (Class representationClass) {
putProperty (PROP_REPRESENTATION_CLASS, representationClass);
}
/** Get the representation class for this data loader.
* @return the class
*/
public final Class getRepresentationClass () {
return (Class)getProperty (PROP_REPRESENTATION_CLASS);
}
/** Get actions.
* These actions are used to compose
* a popup menu for the data object. Also these actions should
* be customizable by the user, so he can modify the popup menu on a
* data object.
*
* @return array of system actions or <CODE>null</CODE> if this loader does not have any
* actions
*/
public final SystemAction[] getActions () {
return (SystemAction[])getProperty (PROP_ACTIONS);
}
/** Set actions.
* <p>Note that this method is public, not protected, so it is possible for anyone
* to modify the loader's popup actions externally (after finding the loader
* using {@link DataLoaderPool#firstProducerOf}).
* While this is possible, anyone doing so must take care to place new actions
* into sensible positions, including consideration of separators.
* This may also adversely affect the intended feel of the data objects.
* A preferable solution is generally to use {@link org.openide.actions.ToolsAction service actions}.
* @param actions actions for this loader or <CODE>null</CODE> if it should not have any
* @see #getActions
*/
public final void setActions (SystemAction[] actions) {
putProperty (PROP_ACTIONS, actions, true);
}
/** Get the current display name of this loader.
* @return display name
*/
public final String getDisplayName () {
return (String)getProperty (PROP_DISPLAY_NAME);
}
/** Set the display name for this loader. Only subclasses should set the name.
* @param displayName new name
*/
protected final void setDisplayName (final String displayName) {
putProperty (PROP_DISPLAY_NAME, displayName, true);
}
/** Find a data object appropriate to the given file object--the meat of this class.
* <p>
* For example: for files with the same basename but extensions <EM>.java</EM> and <EM>.class</EM>, the handler
* should return the same <code>DataObject</code>.
* <P>
* The loader can add all files it has recognized into the <CODE>recognized</CODE>
* buffer. Then all these files will be excluded from further processing.
*
* @param fo file object to recognize
* @param recognized recognized file buffer
* @exception DataObjectExistsException if the data object for the
* primary file already exists
* @exception IOException if the object is recognized but cannot be created
* @exception InvalidClassException if the class is not instance of
* {@link #getRepresentationClass}
*
* @return suitable data object or <CODE>null</CODE> if the handler cannot
* recognize this object (or its group)
* @see #handleFindDataObject
*/
public final DataObject findDataObject (
FileObject fo, RecognizedFiles recognized
) throws IOException {
DataObject obj = handleFindDataObject (fo, recognized);
if (obj != null && !getRepresentationClass ().isInstance (obj)) {
// does not fullfil representation class
throw new java.io.InvalidClassException (obj.getClass ().toString ());
}
return obj;
}
/** Find a data object appropriate to the given file object (as implemented in subclasses).
* @see #findDataObject
* @param fo file object to recognize
* @param recognized recognized file buffer
* @exception DataObjectExistsException as in <code>#findDataObject</code>
* @exception IOException as in <code>#findDataObject</code>
*
* @return the data object or <code>null</code>
*/
protected abstract DataObject handleFindDataObject (
FileObject fo, RecognizedFiles recognized
) throws IOException;
/** Utility method to mark a file as belonging to this loader.
* When the file is to be recognized this loader will be used first.
* <P>
* This method is used by {@link DataObject#markFiles}.
*
* @param fo file to mark
* @exception IOException if setting the file's attribute failed
*/
public final void markFile (FileObject fo) throws IOException {
fo.setAttribute (DataObject.EA_ASSIGNED_LOADER, getClass ().getName ());
}
/** Writes nothing to the stream.
* @param oo ignored
*/
public void writeExternal (ObjectOutput oo) throws IOException {
oo.writeObject (getActions ());
oo.writeUTF (getDisplayName ());
}
/** Reads nothing from the stream.
* @param oi ignored
*/
public void readExternal (ObjectInput oi)
throws IOException, ClassNotFoundException {
setActions ((SystemAction[])oi.readObject ());
setDisplayName (oi.readUTF ());
}
/** Get a registered loader from the pool.
* @param loaderClass exact class of the loader (<em>not</em> its data object representation class)
* @return the loader instance, or <code>null</code> if there is no such loader registered
* @see DataLoaderPool#allLoaders
*/
public static DataLoader getLoader (Class loaderClass) {
return (DataLoader)findObject (loaderClass, true);
}
// XXX huh? --jglick
// The parameter can be <CODE>null</CODE> to
// simplify testing whether the file object fo is valid or not
/** Buffer holding a list of primary and secondary files marked as already recognized, to prevent further scanning.
*/
public interface RecognizedFiles {
/** Mark this file as being recognized. It will be excluded
* from further processing.
*
* @param fo file object to exclude
*/
public void markRecognized (FileObject fo);
}
}
/*
* Log
* 11 Gandalf 1.10 1/12/00 Ian Formanek NOI18N
* 10 Gandalf 1.9 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun
* Microsystems Copyright in File Comment
* 9 Gandalf 1.8 9/30/99 Jaroslav Tulach DataLoader is now
* serializable.
* 8 Gandalf 1.7 9/28/99 Jaroslav Tulach Changes in loader pool
* are reflected in repository.
* 7 Gandalf 1.6 6/10/99 Jesse Glick [JavaDoc]
* 6 Gandalf 1.5 6/8/99 Ian Formanek ---- Package Change To
* org.openide ----
* 5 Gandalf 1.4 4/1/99 Jesse Glick [JavaDoc]
* 4 Gandalf 1.3 4/1/99 Martin Ryzl getLoader() added
* 3 Gandalf 1.2 3/9/99 Jesse Glick [JavaDoc]
* 2 Gandalf 1.1 2/4/99 Petr Hamernik setting of extended file
* attributes doesn't require FileLock
* 1 Gandalf 1.0 1/5/99 Ian Formanek
* $
* Beta Change History:
* 0 Tuborg 1.10 --/--/98 Jaroslav Tulach Added listener for operations on data object,
*/